package com.qutan.app.core.common;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by pwy on 16/5/15
 * 分页sql查询
 */
public interface PSQLDoing<T> extends BaseDoing<T> {

    default Page<T> go(Page page, Class<T> clazz, ObjectMapper objectMapper, NamedParameterJdbcTemplate jdbcTemplate, Logger log) {
        Page<T> outPage = new Page<>();
        StringBuffer sql = new StringBuffer();
        StringBuffer fields = new StringBuffer();
        String countField = "count(1)";
        Map<String, Object> params = new HashMap<>();

        // 数据库对应字段 字符串json 转换 对象
        Map<String, TypeReference> typeReferenceMap = new HashMap<>();
        try {
            this.service(sql, fields, params, typeReferenceMap);
            // 当如果没有自定义需要显示的字段,默认是 *
            if (fields.length() <= 0) {
                fields.append("*");
            }

            String countSql = String.format(sql.toString(), countField);
            String dataSql = String.format(sql.append(" limit :offset,:size").toString(), fields);
            log.info("countSql : {}", countSql);
            log.info("dataSql : {}", dataSql);
            Long count = jdbcTemplate.queryForObject(countSql, params, Long.class);
            if (count == 0) {
                return outPage;
            }
            outPage.totalCount = count;
            params.put("offset", page.offset);
            params.put("size", page.pageSize);
            outPage.pageNo = page.pageNo;
            outPage.pageSize = page.pageSize;


            RBeanPropertyRowMapper rBeanPropertyRowMapper = new RBeanPropertyRowMapper(clazz);
            if (objectMapper != null) {
                rBeanPropertyRowMapper = new RBeanPropertyRowMapper(clazz, objectMapper,typeReferenceMap);
            }

            outPage.result = jdbcTemplate.query(dataSql, params, rBeanPropertyRowMapper);
        } catch (Exception e) {
            this.errorLog(log, e);
        }
        return outPage;
    }

    default Page<T> go(Page page, Class<T> clazz, NamedParameterJdbcTemplate jdbcTemplate, Logger log) {

        return this.go(page, clazz, null, jdbcTemplate, log);
    }

    void service(StringBuffer sql, StringBuffer fields, Map<String, Object> params, Map<String, TypeReference> typeReferenceMap);
}
